//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2007
//
// Dialog for editing point coordinates.
//

# include "StdAfx.h"
# include "Resource.h"
# include "EditPoint.h"
# include "PtAlgo.h"
# include "PrintUnits.h"
# include "ParseHelpers.h"
# include "Dialog.h"
# include "Globals.h"

class CEditPoint : public CDialog {
  public:
	CEditPoint (point_t & _point) : CDialog (IDD_EDIT_POINT), m_point (_point) {}

	// Override.
	virtual bool OnInit (HWND _hwndFocus) {
		char strX [20], strY [20];
		PrintLon (strX, m_point.x);
		PrintLat (strY, m_point.y);

		SetDlgItemTextF (IDC_POSITION, "%s %s", strY, strX);

		EnableDlgItem (IDOK, false);
		return true;
	}

	virtual void OnCommand (WORD _wCmd, WORD _wNotifyCode, HWND _hwndCtl) {
		switch (_wCmd) {
			case IDC_POSITION: {
				if (_wNotifyCode == EN_CHANGE) {
					point_t pt;
					const bool bOK = _ParsePos (pt);
					EnableDlgItem (IDOK, bOK);
				}
				break;
			}

			case IDOK: {
				point_t pt;
				const bool bOK = _ParsePos (pt);
				if (bOK)
					m_point = pt;

				EndDialog (0);
				break;
			}

			case IDCANCEL:
				EndDialog (1);
				break;
		}
	}

  private:
	point_t & m_point;

	bool _ParsePos (point_t & _pt) const;
};

bool CEditPoint::_ParsePos (point_t & _pt) const {
	const HWND hPos = ::GetDlgItem (m_hWnd, IDC_POSITION);

	const size_t cLen = ::GetWindowTextLength (hPos);
	char * const str = reinterpret_cast<char *> (alloca ((cLen + 1)*sizeof (char)));
	::GetWindowText (hPos, str, cLen + 1);
	const char * const pEnd = str + cLen;

	const char * p = str;

	OmitSpaces (& p, pEnd);
	if (* p == 'E' || * p == 'W' || * p == 'N' || * p == 'S') {
		const bool bEW1 = * p == 'E' || * p == 'W';

		float f1;
		if (! ParseArc (p, pEnd, & p, f1, false))
			return false;

		OmitSpaces (& p, pEnd);
		if (* p == ',') {
			++ p;
			OmitSpaces (& p, pEnd);
		}
		const bool bNS2 = * p == 'N' || * p == 'S';

		float f2;
		if (! ParseArc (p, pEnd, & p, f2, false))
			return false;

		OmitSpaces (& p, pEnd);
		if (p != pEnd)
			return false;

		if (bEW1 && bNS2) {
			_pt.x = f1;
			_pt.y = f2;
		} else {
			_pt.x = f2;
			_pt.y = f1;
		}
		return true;
	} else {
		float f1;
		if (! ParseReal (p, pEnd, & p, f1))
			return false;

		OmitSpaces (& p, pEnd);
		if (* p == ',') {
			++ p;
			OmitSpaces (& p, pEnd);
		}

		float f2;
		if (! ParseReal (p, pEnd, & p, f2))
			return false;

		OmitSpaces (& p, pEnd);
		if (p != pEnd)
			return false;

		_pt.x = f2;
		_pt.y = f1;
		return true;
	}
}

bool EditPoint (HWND _hWnd, point_t & _point) {
	CEditPoint epd (_point);
	return epd.ShowModal (_hWnd) == 0;
}